package project.view.tag;

import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Map.Entry;
import java.util.Set;

import javax.servlet.jsp.JspException;

import online.filter.FilterUtil;
import online.view.ViewUtil;
import online.view.model.ViewMap;
import online.view.tag.BaseTag;

/**
 * 全パラメタHidden化タグライブラリ
 *
 * @author Tadashi Nakayama
 * @version 1.0.0
 */
public final class HiddenAllParameterTag extends BaseTag {
	/** serialVersionUID */
	private static final long serialVersionUID = 3213610215784261575L;

	/**
	 * @see javax.servlet.jsp.tagext.TagSupport#doStartTag()
	 */
	@Override
	public int doStartTag() throws JspException {
		Set<String> set = getQueryParamSet();

		Map<String, String[]> pm = super.getRequest().getParameterMap();
		ViewMap vm = super.getViewMap();
		Set<String> done = new HashSet<>();
		for (final Entry<String, String[]> me : pm.entrySet()) {
			String name = me.getKey();
			if (set.contains(name) || done.contains(name)) {
				continue;
			}

			if (vm.containsKey(name)) {
				Object obj = vm.get(name);
				if (Iterable.class.isInstance(obj)) {
					for (final Object o : Iterable.class.cast(obj)) {
						write(name, o);
					}
				} else if (obj != null) {
					write(name, obj);
				}
			} else {
				String[] obj = me.getValue();
				if (obj != null) {
					for (final String o : obj) {
						write(name, sanitize(o));
					}
				}
			}
			done.add(name);
		}
		return SKIP_BODY;
	}

	/**
	 * オブジェクト文字列取得
	 *
	 * @param obj オブジェクト
	 * @return オブジェクト文字列
	 */
	private String sanitize(final String obj) {
		return ViewUtil.sanitize(obj, ViewUtil.getCharset(super.getResponse()), true);
	}

	/**
	 * 出力処理
	 *
	 * @param name 名前
	 * @param value 値
	 */
	private void write(final String name, final Object value) {
		super.output(null, "<input type=\"hidden\" name=\"");
		super.output(null, name);
		super.output(null, "\" value=\"");
		super.output(null, value);
		super.output(null, "\" />", true);
	}

	/**
	 * クエリパラメタ集合取得
	 *
	 * @return クエリパラメタ
	 */
	private Set<String> getQueryParamSet() {
		String query = Objects.toString(FilterUtil.getQueryString(super.getRequest()), "");
		return FilterUtil.toParameterKeySet(query.replaceAll("[<>\"\\(\\)]", ""));
	}
}
